﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

namespace SimpleGameData.Animations
{
    public enum AnimationKey { Move }

    public class Animation
    {
        #region Fields

        // The animation data read from an XML file
        private AnimationData animationData;
        // The Rectangles for each frame used in this animation
        private Rectangle[] frames;
        // The time since we last updated the frame
        private TimeSpan frameTimer;
        // The time we display a frame until the next one
        private TimeSpan frameLength;
        // The index of the current frame we are displaying
        private int currentFrame;

        #endregion

        #region Properties

        public AnimationData AnimationData
        {
            get { return animationData; }
            set { animationData = value; }
        }

        /// <summary>
        /// The current frame rectangle which should be drawn
        /// </summary>
        [ContentSerializerIgnore]
        public Rectangle CurrentFrameRect
        {
            get { return frames[currentFrame]; }
        }

        /// <summary>
        /// The current frame, clamped to avoid "out of bounds" error
        /// </summary>
        [ContentSerializerIgnore]
        public int CurrentFrame
        {
            get { return currentFrame; }
            set
            {
                currentFrame = (int)MathHelper.Clamp(value, 0, frames.Length - 1);
            }
        }

        #endregion

        #region Constructor

        public Animation()
        {

        }

        #endregion

        #region Initialize

        public void Initialize()
        {
            // create array with length based on the amount of frames used in this animation
            frames = new Rectangle[animationData.FrameCount];

            for (int i = 0; i < animationData.FrameCount; i++)
            {
                frames[i] = new Rectangle(
                        (animationData.FrameWidth * i),
                        0,
                        animationData.FrameWidth,
                        animationData.FrameHeight);
            }
            // calculate how long a frame will be displayed
            frameLength = TimeSpan.FromSeconds(1 / (double)animationData.FramesPerSecond);

            Reset();
        }

        #endregion

        #region Methods

        public void Update(GameTime gameTime)
        {
            // Update the elapsed time
            frameTimer += gameTime.ElapsedGameTime;

            // If the elapsed time is larger than the frame length time, move to the next frame
            if (frameTimer >= frameLength)
            {
                // Reset elapsed time
                frameTimer = TimeSpan.Zero;
                // move to next frame and if it is the last frame of the animation set to 0 again
                currentFrame = (currentFrame + 1) % frames.Length;
            }
        }

        /// <summary>
        /// Resets the animation to the beginning meaning the first frame and restart the timers.
        /// </summary>
        public void Reset()
        {
            currentFrame = 0;
            frameTimer = TimeSpan.Zero;
        }

        #endregion
    }
}
